﻿using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace MissionPlanner.Utilities
{
    public class LTM
    {
/* #################################################################################################################
 * LightTelemetry protocol (LTM)
 *
 * Ghettostation one way telemetry protocol for really low bitrates (2400 bauds). 
 *			   
 * Protocol details: 3 different frames, little endian.
 *   G Frame (GPS position) (2 Hz): 18BYTES
 *    0x24 0x54 0x47 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF  0xFF   0xC0
 *     $     T    G  --------LAT-------- -------LON---------  SPD --------ALT-------- SAT/FIX  CRC
 *   A Frame (Attitude) (5 Hz): 10BYTES
 *     0x24 0x54 0x41 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xC0
 *      $     T   A   --PITCH-- --ROLL--- -HEADING-  CRC
 *   S Frame (Sensors) (2 Hz): 11BYTES
 *     0x24 0x54 0x53 0xFF 0xFF  0xFF 0xFF    0xFF    0xFF      0xFF       0xC0
 *      $     T   S   VBAT(mV)  Current(mA)   RSSI  AIRSPEED  ARM/FS/FMOD   CRC
 * ################################################################################################################# */

        const string header = "$T";

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct G
        {
            public Int32 Latitude;
            public Int32 Longitude;
            public byte GroundSpeed;
            public Int32 Altitude;
            public byte Sats_Fix;

            public int GetSats => Sats_Fix >> 2;
            public int GetFix => Sats_Fix & 3;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct A
        {
            public Int16 Pitch;
            public Int16 Roll;
            public Int16 Heading;
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct S
        {
            public UInt16 Vbat;
            public UInt16 Battery_Consumption;
            public byte RSSI;
            public byte Airspeed;
            public byte Status;

            public mode GetMode => (mode) (Status >> 2);
            public bool GetFailsafe => (Status & 0x2) > 0;
            public bool GetArmed => (Status & 0x1) > 0;

            public enum mode
            {
                Manual = 0,
                Rate = 1,
                Angle = 2,
                Horizon = 3,
                Acro = 4,
                Stabilised1 = 5,
                Stabilised2 = 6,
                Stabilised3 = 7,
                AltitudeHold = 8,
                GPSHold = 9,
                Waypoints = 10,
                Headfree = 11,
                Circle = 12,
                RTH = 13,
                Followme = 14,
                Land = 15,
                FlybywireA = 16,
                FlybywireB = 17,
                Cruise = 18,
                Unknown = 19,
                Launch = 20,
                Autotune = 21,
            }
        }

        [StructLayout(LayoutKind.Sequential, Pack = 1)]
        public struct O
        {
            public Int32 Latitude;
            public Int32 Longitude;
            public Int32 Altitude;
            public byte OSDon;
            public byte Fix;
        }

        public void test()
        {
            byte[] data =
            {
                0x24, 0x54, 0x47, 0xA7, 0xFD, 0xEB, 0xEA, 0x14, 0xCD, 0xE8, 0x58, 0x03,
                0xBE, 0x0B, 0x00, 0x00, 0x2B, 0xAF, 0x24, 0x54, 0x41, 0x0F, 0x00, 0x07,
                0x00, 0x53, 0x00, 0x5B, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x10, 0x00, 0x08, 0x00, 0x52, 0x00,
                0x4A, 0x24, 0x54, 0x47, 0x68, 0xFD, 0xEB, 0xEA, 0xA2, 0xCC, 0xE8, 0x58,
                0x03, 0xC2, 0x0B, 0x00, 0x00, 0x2B, 0xAB, 0x24, 0x54, 0x41, 0x10, 0x00,
                0x08, 0x00, 0x52, 0x00, 0x4A, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x11, 0x00, 0x08, 0x00, 0x53,
                0x00, 0x4A, 0x24, 0x54, 0x41, 0x11, 0x00, 0x09, 0x00, 0x53, 0x00, 0x4B,
                0x24, 0x54, 0x47, 0x0E, 0xFD, 0xEB, 0xEA, 0x00, 0xCC, 0xE8, 0x58, 0x04,
                0xC7, 0x0B, 0x00, 0x00, 0x2B, 0x6D, 0x24, 0x54, 0x41, 0x12, 0x00, 0x09,
                0x00, 0x53, 0x00, 0x48, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x12, 0x00, 0x0A, 0x00, 0x53, 0x00,
                0x4B, 0x24, 0x54, 0x47, 0xBD, 0xFC, 0xEB, 0xEA, 0x6D, 0xCB, 0xE8, 0x58,
                0x04, 0xCD, 0x0B, 0x00, 0x00, 0x2B, 0xBF, 0x24, 0x54, 0x41, 0x13, 0x00,
                0x0A, 0x00, 0x53, 0x00, 0x4A, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x13, 0x00, 0x0A, 0x00, 0x53,
                0x00, 0x4A, 0x24, 0x54, 0x41, 0x14, 0x00, 0x0A, 0x00, 0x53, 0x00, 0x4D,
                0x24, 0x54, 0x47, 0x4D, 0xFC, 0xEB, 0xEA, 0xA3, 0xCA, 0xE8, 0x58, 0x04,
                0xD3, 0x0B, 0x00, 0x00, 0x2B, 0x9E, 0x24, 0x54, 0x41, 0x14, 0x00, 0x0A,
                0x00, 0x53, 0x00, 0x4D, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x14, 0x00, 0x0A, 0x00, 0x53, 0x00,
                0x4D, 0x24, 0x54, 0x47, 0xEA, 0xFB, 0xEB, 0xEA, 0xF1, 0xC9, 0xE8, 0x58,
                0x05, 0xD9, 0x0B, 0x00, 0x00, 0x2B, 0x64, 0x24, 0x54, 0x41, 0x15, 0x00,
                0x0A, 0x00, 0x53, 0x00, 0x4C, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x15, 0x00, 0x0A, 0x00, 0x53,
                0x00, 0x4C, 0x24, 0x54, 0x41, 0x15, 0x00, 0x0A, 0x00, 0x53, 0x00, 0x4C,
                0x24, 0x54, 0x47, 0x65, 0xFB, 0xEB, 0xEA, 0x02, 0xC9, 0xE8, 0x58, 0x05,
                0xE1, 0x0B, 0x00, 0x00, 0x2B, 0x20, 0x24, 0x54, 0x41, 0x15, 0x00, 0x0B,
                0x00, 0x53, 0x00, 0x4D, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x15, 0x00, 0x0B, 0x00, 0x53, 0x00,
                0x4D, 0x24, 0x54, 0x47, 0xF4, 0xFA, 0xEB, 0xEA, 0x37, 0xC8, 0xE8, 0x58,
                0x06, 0xE8, 0x0B, 0x00, 0x00, 0x2B, 0x8E, 0x24, 0x54, 0x41, 0x16, 0x00,
                0x0B, 0x00, 0x53, 0x00, 0x4E, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x16, 0x00, 0x0B, 0x00, 0x53,
                0x00, 0x4E, 0x24, 0x54, 0x41, 0x16, 0x00, 0x0B, 0x00, 0x53, 0x00, 0x4E,
                0x24, 0x54, 0x47, 0x60, 0xFA, 0xEB, 0xEA, 0x2D, 0xC7, 0xE8, 0x58, 0x06,
                0xF0, 0x0B, 0x00, 0x00, 0x2B, 0x17, 0x24, 0x54, 0x41, 0x16, 0x00, 0x0B,
                0x00, 0x53, 0x00, 0x4E, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x16, 0x00, 0x0B, 0x00, 0x53, 0x00,
                0x4E, 0x24, 0x54, 0x47, 0xE5, 0xF9, 0xEB, 0xEA, 0x4E, 0xC6, 0xE8, 0x58,
                0x06, 0xF6, 0x0B, 0x00, 0x00, 0x2B, 0xF5, 0x24, 0x54, 0x41, 0x16, 0x00,
                0x0B, 0x00, 0x53, 0x00, 0x4E, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x17, 0x00, 0x0B, 0x00, 0x53,
                0x00, 0x4F, 0x24, 0x54, 0x41, 0x17, 0x00, 0x0B, 0x00, 0x53, 0x00, 0x4F,
                0x24, 0x54, 0x47, 0x44, 0xF9, 0xEB, 0xEA, 0x2E, 0xC5, 0xE8, 0x58, 0x06,
                0xFF, 0x0B, 0x00, 0x00, 0x2B, 0x3E, 0x24, 0x54, 0x41, 0x17, 0x00, 0x0B,
                0x00, 0x53, 0x00, 0x4F, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x17, 0x00, 0x0C, 0x00, 0x53, 0x00,
                0x48, 0x24, 0x54, 0x47, 0xC0, 0xF8, 0xEB, 0xEA, 0x40, 0xC4, 0xE8, 0x58,
                0x07, 0x05, 0x0C, 0x00, 0x00, 0x2B, 0x28, 0x24, 0x54, 0x41, 0x17, 0x00,
                0x0C, 0x00, 0x53, 0x00, 0x48, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x17, 0x00, 0x0C, 0x00, 0x53,
                0x00, 0x48, 0x24, 0x54, 0x41, 0x17, 0x00, 0x0C, 0x00, 0x53, 0x00, 0x48,
                0x24, 0x54, 0x47, 0x16, 0xF8, 0xEB, 0xEA, 0x0E, 0xC3, 0xE8, 0x58, 0x07,
                0x0D, 0x0C, 0x00, 0x00, 0x2B, 0xBF, 0x24, 0x54, 0x41, 0x17, 0x00, 0x0C,
                0x00, 0x53, 0x00, 0x48, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x18, 0x00, 0x0C, 0x00, 0x53, 0x00,
                0x47, 0x24, 0x54, 0x47, 0x8A, 0xF7, 0xEB, 0xEA, 0x14, 0xC2, 0xE8, 0x58,
                0x07, 0x14, 0x0C, 0x00, 0x00, 0x2B, 0x2E, 0x24, 0x54, 0x41, 0x18, 0x00,
                0x0C, 0x00, 0x53, 0x00, 0x47, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x18, 0x00, 0x0C, 0x00, 0x53,
                0x00, 0x47, 0x24, 0x54, 0x41, 0x18, 0x00, 0x0C, 0x00, 0x53, 0x00, 0x47,
                0x24, 0x54, 0x47, 0xD8, 0xF6, 0xEB, 0xEA, 0xD5, 0xC0, 0xE8, 0x58, 0x07,
                0x1C, 0x0C, 0x00, 0x00, 0x2B, 0xB6, 0x24, 0x54, 0x41, 0x18, 0x00, 0x0C,
                0x00, 0x53, 0x00, 0x47, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x18, 0x00, 0x0C, 0x00, 0x53, 0x00,
                0x47, 0x24, 0x54, 0x47, 0x48, 0xF6, 0xEB, 0xEA, 0xD1, 0xBF, 0xE8, 0x58,
                0x07, 0x22, 0x0C, 0x00, 0x00, 0x2B, 0x63, 0x24, 0x54, 0x41, 0x18, 0x00,
                0x0C, 0x00, 0x53, 0x00, 0x47, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x18, 0x00, 0x0C, 0x00, 0x53,
                0x00, 0x47, 0x24, 0x54, 0x41, 0x18, 0x00, 0x0C, 0x00, 0x53, 0x00, 0x47,
                0x24, 0x54, 0x47, 0x8F, 0xF5, 0xEB, 0xEA, 0x87, 0xBE, 0xE8, 0x58, 0x07,
                0x2A, 0x0C, 0x00, 0x00, 0x2B, 0xF8, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0C,
                0x00, 0x53, 0x00, 0x46, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0C, 0x00, 0x53, 0x00,
                0x46, 0x24, 0x54, 0x47, 0xFA, 0xF4, 0xEB, 0xEA, 0x7A, 0xBD, 0xE8, 0x58,
                0x07, 0x30, 0x0C, 0x00, 0x00, 0x2B, 0x68, 0x24, 0x54, 0x41, 0x19, 0x00,
                0x0C, 0x00, 0x53, 0x00, 0x46, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0C, 0x00, 0x53,
                0x00, 0x46, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0C, 0x00, 0x53, 0x00, 0x46,
                0x24, 0x54, 0x47, 0x3C, 0xF4, 0xEB, 0xEA, 0x24, 0xBC, 0xE8, 0x58, 0x07,
                0x39, 0x0C, 0x00, 0x00, 0x2B, 0xF8, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0C,
                0x00, 0x53, 0x00, 0x46, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0C, 0x00, 0x53, 0x00,
                0x46, 0x24, 0x54, 0x47, 0xA2, 0xF3, 0xEB, 0xEA, 0x10, 0xBB, 0xE8, 0x58,
                0x08, 0x3F, 0x0C, 0x00, 0x00, 0x2B, 0x5B, 0x24, 0x54, 0x41, 0x19, 0x00,
                0x0D, 0x00, 0x53, 0x00, 0x47, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0D, 0x00, 0x53,
                0x00, 0x47, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0D, 0x00, 0x53, 0x00, 0x47,
                0x24, 0x54, 0x47, 0xDF, 0xF2, 0xEB, 0xEA, 0xB3, 0xB9, 0xE8, 0x58, 0x08,
                0x47, 0x0C, 0x00, 0x00, 0x2B, 0xFE, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0D,
                0x00, 0x53, 0x00, 0x47, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0D, 0x00, 0x53, 0x00,
                0x47, 0x24, 0x54, 0x47, 0x41, 0xF2, 0xEB, 0xEA, 0x98, 0xB8, 0xE8, 0x58,
                0x08, 0x4E, 0x0C, 0x00, 0x00, 0x2B, 0x43, 0x24, 0x54, 0x41, 0x19, 0x00,
                0x0D, 0x00, 0x53, 0x00, 0x47, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0D, 0x00, 0x53,
                0x00, 0x47, 0x24, 0x54, 0x41, 0x19, 0x00, 0x0D, 0x00, 0x53, 0x00, 0x47,
                0x24, 0x54, 0x47, 0x7B, 0xF1, 0xEB, 0xEA, 0x33, 0xB7, 0xE8, 0x58, 0x08,
                0x56, 0x0C, 0x00, 0x00, 0x2B, 0xC6, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D,
                0x00, 0x53, 0x00, 0x44, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D, 0x00, 0x53, 0x00,
                0x44, 0x24, 0x54, 0x47, 0xDB, 0xF0, 0xEB, 0xEA, 0x14, 0xB6, 0xE8, 0x58,
                0x08, 0x5C, 0x0C, 0x00, 0x00, 0x2B, 0x4B, 0x24, 0x54, 0x41, 0x1A, 0x00,
                0x0D, 0x00, 0x53, 0x00, 0x44, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D, 0x00, 0x53,
                0x00, 0x44, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D, 0x00, 0x53, 0x00, 0x44,
                0x24, 0x54, 0x47, 0x11, 0xF0, 0xEB, 0xEA, 0xA9, 0xB4, 0xE8, 0x58, 0x08,
                0x64, 0x0C, 0x00, 0x00, 0x2B, 0x06, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D,
                0x00, 0x53, 0x00, 0x44, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D, 0x00, 0x53, 0x00,
                0x44, 0x24, 0x54, 0x47, 0x6E, 0xEF, 0xEB, 0xEA, 0x85, 0xB3, 0xE8, 0x58,
                0x08, 0x6A, 0x0C, 0x00, 0x00, 0x2B, 0x43, 0x24, 0x54, 0x41, 0x1A, 0x00,
                0x0D, 0x00, 0x53, 0x00, 0x44, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00,
                0x00, 0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D, 0x00, 0x53,
                0x00, 0x44, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D, 0x00, 0x53, 0x00, 0x44,
                0x24, 0x54, 0x47, 0xA2, 0xEE, 0xEB, 0xEA, 0x16, 0xB2, 0xE8, 0x58, 0x08,
                0x72, 0x0C, 0x00, 0x00, 0x2B, 0x04, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D,
                0x00, 0x53, 0x00, 0x44, 0x24, 0x54, 0x53, 0x01, 0x61, 0x00, 0x00, 0x00,
                0x00, 0x0D, 0x6D, 0x24, 0x54, 0x41, 0x1A, 0x00, 0x0D, 0x00, 0x53, 0x00,
                0x44, 0x24, 0x54, 0x47, 0xFD, 0xED, 0xEB, 0xEA, 0xED, 0xB0, 0xE8, 0x58,
                0x08, 0x79, 0x0C, 0x00, 0x00, 0x2B, 0xAA, 0x24, 0x54
            };

            NewStatusMessage += (sender, s) => Console.WriteLine(s.ToJSON());
            NewAttitudeMessage += (sender, s) => Console.WriteLine(s.ToJSON());
            NewGPSMessage += (sender, s) => Console.WriteLine(s.ToJSON());

            data.ForEach(a => NewByte(a));
        }

        private byte[] packet = new byte[100];
        private int payload = 0;
        private byte crc = 0;
        private int state = 0;
        public event EventHandler<S> NewStatusMessage;
        public event EventHandler<A> NewAttitudeMessage;
        public event EventHandler<G> NewGPSMessage;

        public void NewByte(byte data)
        {
            switch (state)
            {
                default:
                case 0:
                    if (data == header[0])
                    {
                        packet[state] = data;
                        state++;
                    }
                    else
                    {
                        state = 0;
                    }

                    break;
                case 1:
                    if (data == header[1])
                    {
                        packet[state] = data;
                        state++;
                    }
                    else
                    {
                        state = 0;
                    }

                    break;
                case 2:
                    packet[state] = data;
                    state++;
                    crc = 0;
                    payload = 0;
                    break;
                case 3:
                    packet[state + payload] = data;
                    switch ((char) packet[2])
                    {
                        case 'G':
                            if (state + 1 + payload == 18)
                            {
                                if (packet[state + payload] == crc)
                                {
                                    state = 0;
                                    NewLine(packet);
                                }

                                state = 0;
                            }

                            break;
                        case 'A':
                            if (state + 1 + payload == 10)
                            {
                                if (packet[state + payload] == crc)
                                {
                                    state = 0;
                                    NewLine(packet);
                                }

                                state = 0;
                            }

                            break;
                        case 'S':
                            if (state + 1 + payload == 11)
                            {
                                if (packet[state + payload] == crc)
                                {
                                    state = 0;
                                    NewLine(packet);
                                }

                                state = 0;
                            }

                            break;
                        default:
                            state = 0;
                            break;
                    }

                    crc ^= data;
                    payload++;
                    break;
            }
        }

        void NewLine(byte[] line)
        {
            if (line.Length > 3 && line[0] == header[0] && line[1] == header[1])
            {
                switch ((char) line[2])
                {
                    case 'G':
                        var lenG = 18;
                        NewGPSMessage?.Invoke(this, line.ByteArrayToStructure<G>(3));
                        break;
                    case 'A':
                        var lenA = 10;
                        NewAttitudeMessage?.Invoke(this, line.ByteArrayToStructure<A>(3));
                        break;
                    case 'S':
                        var lenS = 11;
                        NewStatusMessage?.Invoke(this, line.ByteArrayToStructure<S>(3));
                        break;
                    case 'O':

                        break;
                    case 'N':

                        break;
                    case 'X':

                        break;
                }
            }
        }
    }
}
